﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Security;
using Unknown.Framework.Develop;
using Unknown.Framework.General;
using Unknown.Framework.Storage;
using Unknown.Framework.Transform;

namespace Unknown.Framework.Configuration
{
    /// <summary>
    /// 配置抽象类
    /// </summary>
    /// <typeparam name="T">对象</typeparam>
    public abstract class AbstractConfigurationHandler<T> : IConfigurationHandler<T> where T : new()
    {
        /// <summary>
        /// 匹配字符串
        /// </summary>
        protected abstract string SearchPattern { get; }
        /// <summary>
        /// 示例值
        /// </summary>
        protected abstract T ExampleValue { get; }

        /// <summary>
        /// 读
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns>数据</returns>
        protected virtual T Read(string file)
        {
            T result = new T();

            string value = XmlFileHandler.Read(file);
            if (!string.IsNullOrEmpty(value))
            {
                object target = ObjectHandler.DeserializeXml(value, typeof(T));
                if (target != null)
                {
                    result = (T)target;
                }
            }

            return result;
        }

        /// <summary>
        /// 写
        /// </summary>
        /// <param name="file">文件</param>
        /// <param name="value">数据</param>
        protected virtual void Write(string file, T value)
        {
            if (value != null)
            {
                string content = ObjectHandler.SerializeXml(value, typeof(T));

                XmlFileHandler.Write(file, content);
            }
        }

        /// <summary>
        /// 示例
        /// </summary>
        public virtual void Example()
        {
            Type type = this.GetType();
            string file = string.Empty;

            file = string.Format(Variable.Culture, "{0}{1}Configuration{1}{2}{3}", Variable.Develop, Variable.PathSeparator, type.FullName, this.SearchPattern);

            this.Write(file, this.ExampleValue);
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="value">值</param>
        protected abstract void Resolve(T value);

        /// <summary>
        /// 构建
        /// </summary>
        /// <param name="directory">目录</param>
        /// <param name="searchPattern">匹配字符串</param>
        public virtual void Build(string directory, string searchPattern)
        {
            if ((!string.IsNullOrEmpty(directory)) && (!string.IsNullOrEmpty(searchPattern)))
            {
                try
                {
                    DirectoryInfo directoryInfo = new DirectoryInfo(directory);
                    FileInfo[] fileInfos = directoryInfo.GetFiles(searchPattern, SearchOption.AllDirectories);
                    if (fileInfos != null)
                    {
                        foreach (FileInfo fileInfo in fileInfos)
                        {
                            T value = this.Read(fileInfo.FullName);
                            this.Resolve(value);
                        }
                    }
                }
                catch (ArgumentNullException exception)
                {
                    Collection<string> remarks = new Collection<string>();
                    remarks.Add(directory);
                    remarks.Add(searchPattern);

                    CrashHandlers.Default.Hibernate(exception, remarks);
                }
                catch (ArgumentOutOfRangeException exception)
                {
                    Collection<string> remarks = new Collection<string>();
                    remarks.Add(directory);
                    remarks.Add(searchPattern);

                    CrashHandlers.Default.Hibernate(exception, remarks);
                }
                catch (ArgumentException exception)
                {
                    Collection<string> remarks = new Collection<string>();
                    remarks.Add(directory);
                    remarks.Add(searchPattern);

                    CrashHandlers.Default.Hibernate(exception, remarks);
                }
                catch (DirectoryNotFoundException exception)
                {
                    Collection<string> remarks = new Collection<string>();
                    remarks.Add(directory);
                    remarks.Add(searchPattern);

                    CrashHandlers.Default.Hibernate(exception, remarks);
                }
                catch (PathTooLongException exception)
                {
                    Collection<string> remarks = new Collection<string>();
                    remarks.Add(directory);
                    remarks.Add(searchPattern);

                    CrashHandlers.Default.Hibernate(exception, remarks);
                }
                catch (SecurityException exception)
                {
                    Collection<string> remarks = new Collection<string>();
                    remarks.Add(directory);
                    remarks.Add(searchPattern);

                    CrashHandlers.Default.Hibernate(exception, remarks);
                }
            }
        }

        /// <summary>
        /// 构建
        /// </summary>
        /// <param name="directory">目录</param>
        public virtual void Build(string directory)
        {
            string searchPattern = string.Format(Variable.Culture, "*{0}", this.SearchPattern);
            this.Build(directory, searchPattern);
        }
    }
}
